#include<iostream>
#include <stdlib.h>
#include <cstdlib>
#include <ctime>
using namespace std;
#include "../header/Map.h"
#include "../header/JoueurHumain.h"
#include "../header/JoueurOrdinateur.h"
#include "../header/Save.h"
#include "../header/Load.h"

int main(int argc, char **argv) {
	std::srand(std::time(0)); // use current time as seed for random generator
	bool reJouer = true;
	bool mauvaiseSaisie1 = true;
	bool mauvaiseSaisie2 = true;
	bool mauvaiseSaisie3 = true;
	int ligneImpa = 1;
	int colonneImpa = 1;
	int num = 5;
	int touche = 0;
	int typeMap = 0;
	int robot = 0;
	Joueur *j1;
	Joueur *j2;
	Joueur *jPremier;
	Joueur *jDeuxieme;
	Map *plateau = new Map();
	string choix;
	string touchStr = "";
	string texteSave = "";
	cout << "Bienvenue dans Drole de Zebre" << endl;
	while (reJouer) {
		cout << "Menu Principal: " << endl;
		while (mauvaiseSaisie1) {
			/* Choix : Nouvelle Partie ou Charger Partie */
			cout
					<< "Voulez-vous demarrer une nouvelle partie (1) , charger une deja existante (2) ou quitter le jeu (3) ?"
					<< endl;
			cin >> choix;
			/* Nouvelle Partie */
			if (choix.compare("1") == 0) {
				mauvaiseSaisie1 = false;
				cout << "Nouvelle Partie" << endl;
				/*Choix : Joueur Vs Ordinateur ou Joueur Vs Joueur*/

				while (mauvaiseSaisie2) {

					choix = "";
					cout
							<< "Voulez-vous jouer contre un ordinateur (1) ou contre un autre joueur (2) ?"
							<< endl;
					cin >> choix;
					/* Joueur Vs Ordinateur */
					if (choix.compare("1") == 0) {
						mauvaiseSaisie2 = false;
						cout << "Joueur Vs Ordinateur" << endl;
						cout << "Quel est le nom de votre joueur? : " << endl;
						string nom;
						cin >> nom;
						/* Constructeur de joueur et joueurIA */
						j1 = new JoueurHumain(nom, 1, plateau);

						j2 = new JoueurOrdinateur(2, plateau);
						cout << "L'ordinateur aura la couleur Rouge " << endl;

						robot = 1;

						/* Joueur Vs Joueur */
					} else if (choix.compare("2") == 0) {
						cout << "Joueur Vs Joueur" << endl;
						mauvaiseSaisie2 = false;
						cout << "Quel est le nom du joueur 1 (Vert)? : "
								<< endl;
						string nom;
						cin >> nom;
						/* Constructeur de joueur 1*/
						j1 = new JoueurHumain(nom, 1, plateau);
						cout << "Quel est le nom du joueur 2 (Rouge)? : "
								<< endl;
						nom = "";
						cin >> nom;
						/* Constructeur de joueur 2*/
						j2 = new JoueurHumain(nom, 2, plateau);

					} else {
						cout << "Saisie incorrecte" << endl;

					}
				}

				while (touche == 0) {
					touchStr = "";
					cout << "Sur quelle map voulez vous jouer ? " << endl;
					cout << "(1) pour le plateau par default." << endl;
					cout << "(2) pour le plateau president." << endl;
					cin >> touchStr;
					typeMap = atoi(touchStr.c_str());

					if (typeMap < 1 || typeMap > 2) {

						cout << "Saisie incorrecte " << endl;
						touche = 0;
					} else {
						touche = 1;
					}

				}
				touche = 0;

				if (typeMap == 2) {
					j1->getMap()->presidentMap();
					j1->getMap()->affichePlateau();
				}

				while (touche == 0) {
					touchStr = "";
					cout << " Entrez les coordonnes de Impala : " << endl;
					cout << "(1) pour la premiere ligne." << endl;
					cout << "(2) pour la deuxieme ligne." << endl;
					cout << "(3) pour la premiere colonne." << endl;
					cout << "(4) pour la deuxieme colonne." << endl;
					cout << "(5) pour un Impala par default." << endl;

					cin >> touchStr;
					num = atoi(touchStr.c_str());
					if (num < 0 || num > 6) {

						cout << "Saisie incorrecte " << endl;
						touche = 0;
					} else {
						touche = 1;
					}

				}

				touche = 0;
				while (touche == 0) {

					switch (num) {
					case 1:
						cout << " Numero de la colonne (de 1 a 6)";
						touchStr = "";
						cin >> touchStr;
						colonneImpa = atoi(touchStr.c_str());

						if ((colonneImpa > 0) && (colonneImpa < 7)) {
							ligneImpa = 0;
							touche = 1;
						}
						break;
					case 2:
						cout << " Numero de la colonne (de 1 a 6)";
						touchStr = "";
						cin >> touchStr;
						colonneImpa = atoi(touchStr.c_str());

						if ((colonneImpa > 0) && (colonneImpa < 7)) {
							ligneImpa = 6;
							touche = 1;
						}

						break;
					case 3:

						cout << " Numero de la ligne (de 1 a 5)";
						touchStr = "";
						cin >> touchStr;
						ligneImpa = atoi(touchStr.c_str());

						if ((ligneImpa > 0) && (ligneImpa < 6)) {
							colonneImpa = 0;
							touche = 1;
						}
						break;

					case 4:
						cout << " Numero de la ligne (de 1 a 5)";
						touchStr = "";
						cin >> touchStr;
						ligneImpa = atoi(touchStr.c_str());

						if ((ligneImpa > 0) && (ligneImpa < 6)) {
							colonneImpa = 7;
							touche = 1;
						}
						break;
					case 5:
						ligneImpa = 0;
						colonneImpa = 1;
						touche = 1;
						break;

					}

					if (touche == 0) {

						cout << "Saisie incorrecte " << endl;
					}
				}
				j1->getMap()->getImpala()->setPosX(ligneImpa);
				j1->getMap()->getImpala()->setPosY(colonneImpa);
				/* Charger Partie */
			} else if (choix.compare("2") == 0) {

				robot = robotLoad();
				string nom = "ea";

				if (robot == 0) {

					jPremier = new JoueurHumain(nom, 1, plateau);

					jDeuxieme = new JoueurHumain(nom, 2, plateau);

					if (Load(jPremier, jDeuxieme) == true) {

						mauvaiseSaisie1 = false;
						cout << "Chargement de la partie en cours..." << endl;
						if (jPremier->getMap()->getTour() == 1) {
							j1 = new JoueurHumain("nana", 1, plateau);
							j2 = new JoueurHumain("nini", 2, plateau);
							j1 = jPremier;
							j2 = jDeuxieme;
						} else {
							j1 = new JoueurHumain("nana", 1, plateau);
							j2 = new JoueurHumain("nini", 2, plateau);
							j2 = jPremier;
							j1 = jDeuxieme;
						}

					} else {
						cout << "Pas de sauvegarde." << endl;

					}

				}

				if (robot == 1) {
					jPremier = new JoueurHumain(nom, 1, plateau);
					jDeuxieme = new JoueurOrdinateur(2, plateau);

					if (Load(jPremier, jDeuxieme) == true) {

						mauvaiseSaisie1 = false;
						cout << "Chargement de la partie en cours..." << endl;
						if (jPremier->getMap()->getTour() == 1) {
							j1 = new JoueurHumain("nana", 1, plateau);
							j2 = new JoueurOrdinateur(2, plateau);
							j1 = jPremier;
							j2 = jDeuxieme;
						} else {
							j1 = new JoueurHumain("nana", 1, plateau);
							j2 = new JoueurOrdinateur(2, plateau);
							j2 = jPremier;
							j1 = jDeuxieme;
						}

					} else {
						cout << "Pas de sauvegarde." << endl;

					}

				}

			}

			else if (choix.compare("3") == 0) {
				cout << "Merci d'avoir joue a Drole de Zebre! A bientot !"
						<< endl;
				return 0;
			} else {
				cout << "Saisie incorrecte" << endl;
			}
		}

		/* Debut de la partie */
		cout << "Debut de la partie " << endl;
		bool condArret = true;
		while (condArret) {

			/* Affichage du plateau */
			plateau->affichePlateau();

			/* Condition d'arret */
			if (j1->getNbPion() == 0 && j2->getNbPion() == 0) {
				condArret = false;
			}

			/* Tour du Joueur 1 */

			j1->retireGazelleJoueur(); //on verifie si il faut retirer les gazelle______

			bool tourFini = true;

			if (j1->getNbPion() > 0) {
				while (tourFini) {
					int choixJ = j1->jouer();
					if (choixJ == 1) {
						cout
								<< "Merci d'avoir joue a Drole de Zebre! A bientot !"
								<< endl;
						delete (j1);
						delete (j2);
						return 0;
					}

					else if (choixJ == 2) { //on sauvegarde mais on reste dans le jeu
						cout << "Partie sauvegarde!" << endl;
						save(j1, j2, 1,robot);
					} else if (choixJ == 3) { //on sauvegarde mais on quitte  le jeu
						cout << "Partie sauvegarde!" << endl;
						save(j1, j2, 1,robot);
						cout
								<< "Merci d'avoir joue a Drole de Zebre! A bientot !"
								<< endl;

						delete (j1);
						delete (j2);
						return 0;
					} else {
						tourFini = false;
					}
				}

			}
			j1->retireGazelleJoueur(); //on verifie si il faut retirer les gazelle______
			j2->retireGazelleJoueur(); //on verifie si il faut retirer les gazelle___
			/* On verifie si l'inauguration a deja eu lieu */
			if (!j1->isInauguration() && !j2->isInauguration()) {
				if (j1->getMap()->checkInauguration()) {
					j1->setInauguration(true);
					cout << "J1 a l'inauguration !" << endl;
				}
			}
			/* Affichage du plateau */
			plateau->affichePlateau();
			/* Condition d'arret */
			if (j1->getNbPion() == 0 && j2->getNbPion() == 0) {

				condArret = false;
			}
			tourFini = true;
			/* Tour du Joueur 2 */
			if (j2->getNbPion() > 0) {
				while (tourFini) {
					int choixJ = j2->jouer();
					if (choixJ == 1) {
						cout
								<< "Merci d'avoir joue a Drole de Zebre! A bientot !"
								<< endl;
						delete (j1);
						delete (j2);
						return 0;
					}

					else if (choixJ == 2) { //on sauvegarde mais on reste dans le jeu
						cout << "Partie sauvegarde!" << endl;
						save(j1, j2, 2,robot);
					} else if (choixJ == 3) { //on sauvegarde mais on quitte  le jeu
						cout << "Partie sauvegarde!" << endl;
						save(j1, j2, 2,robot);
						cout
								<< "Merci d'avoir joue a Drole de Zebre! A bientot !"
								<< endl;
						delete (j1);
						delete (j2);
						return 0;
					} else {
						tourFini = false;
					}
				}

			}
			j2->retireGazelleJoueur(); //on verifie si il faut retirer les gazelle_________
			if (!j1->isInauguration() && !j2->isInauguration()) {
				if (j2->getMap()->checkInauguration()) {
					j2->setInauguration(true);
					cout << "J2 a l'inauguration !" << endl;
				}
			}

		}

		cout << "Fin de la partie " << endl;
		/* Calcul des score de chacun */
		for (int k = 0; k < 6; k++) {
			int i = 0;
			int nbVert = 0;
			int nbRouge = 0;
			int scoreZone = 0;
			while (plateau->getSecteur(k, i, 0) != 0 && i < 9) {
				/* Si la case possede un pion Vert */
				if (plateau->getPlateau(plateau->getSecteur(k, i, 0),
						plateau->getSecteur(k, i, 1))->getP()->getCouleur()
						== 1) {
					nbVert++;
				}
				/* Si la case possede un pion Rouge*/
				else if (plateau->getPlateau(plateau->getSecteur(k, i, 0),
						plateau->getSecteur(k, i, 1))->getP()->getCouleur()
						== 2) {
					nbRouge++;
				}

				scoreZone += plateau->getPlateau(plateau->getSecteur(k, i, 0),
						plateau->getSecteur(k, i, 1))->getP()->getVal();

				i++;
			}
			/* Si le Vert a gagne la zone */
			if (nbVert > nbRouge) {
				cout << "Le joueur 1 remporte la zone " << k + 1
						<< " possedant un score de " << scoreZone << endl;
				j1->setScore(j1->getScore() + scoreZone);
			} else {
				cout << "Le joueur 2 remporte la zone " << k + 1
						<< " possedant un score de " << scoreZone << endl;
				j2->setScore(j2->getScore() + scoreZone);
			}
		}
		/* Points de l'inauguration */
		if (j1->isInauguration()) {
			j1->setScore(j1->getScore() + 5);
		} else if (j2->isInauguration()) {
			j2->setScore(j2->getScore() + 5);
		}

		/* Resultat */
		cout << "Score du Joueur numero 1 " << j1->getNom() << " : "
				<< j1->getScore() << endl;
		cout << "Score du Joueur numero 2 " << j2->getNom() << " : "
				<< j2->getScore() << endl;

		if (j1->getScore() > j2->getScore()) {
			cout << "Le joueur 1 a gagne !" << endl;
		} else if (j1->getScore() < j2->getScore()) {
			cout << "Le joueur 2 a gagne !" << endl;
		} else {
			cout << "Egalite.." << endl;
		}

		while (mauvaiseSaisie3) {
			cout << "Voulez vous retourner au menu principal (1) ou Quitter (2)"
					<< endl;
			choix = "";
			cin >> choix;
			if (choix.compare("1") == 0) {
				mauvaiseSaisie3 = false;
			} else if (choix.compare("2") == 0) {
				mauvaiseSaisie3 = false;
				reJouer = false;
			} else {
				cout << "Saisie incorrecte" << endl;
			}
		}
		mauvaiseSaisie1 = true;
		mauvaiseSaisie2 = true;
		mauvaiseSaisie3 = true;

	}
	cout << "Merci d'avoir joue a Drole de Zebre! A bientot !" << endl;
	delete (j1);
	delete (j2);
	return 0;
}
